package com.wushijia.highconcurrency.locksupport;

import java.util.concurrent.locks.LockSupport;

/**
 * description:LockSupport.park()：1、阻塞当前线程；2、支持中断影响，但不会抛出InterruptedException异常，只是默默的返回
 * 《Java并发编程之美》
 *
 * @author yang
 * @date 2018/5/18 21:17
 */
public class LockSupportDemo1 {

  public static final Object u = new Object();
  static ChangeObjectThread t1 = new ChangeObjectThread("t1");
  static ChangeObjectThread t2 = new ChangeObjectThread("t2");


  public static class ChangeObjectThread extends Thread {

    public ChangeObjectThread(String name) {
      super.setName(name);
    }

    @Override
    public void run() {
      synchronized (u) {
        System.out.println("in " + getName());
        LockSupport.park();
        //因调用park方法而被阻塞的线程被其他线程中断而返回，并不会抛出InterruptedException异常。
        if (Thread.interrupted()) {
          System.out.println(getName() + " 被中断了");
        }
      }
      System.out.println(getName() + "执行结束");
    }
  }

  public static void main(String[] args) throws InterruptedException {

    t1.start();
    Thread.sleep(100);
    //子线程t2启动后调用park方法，由于在默认情况下子线程没有持有许可证，因而它会把自己挂起。
    t2.start();
    //如果其他线程调用了阻塞线程t1的interrupt方法 ，设置了中断标志或者线程被虚假唤醒，则阻塞线程也会返回
    t1.interrupt();
    //当一个线程调用unpark时，如果参数thread线程没有持有thread与LockSupport关联的许可证，则让thread线程持有。
    //如果thread之前因调用park()而被挂起，则调用unpark方法后，该线程会被唤醒
    //如果thread之前没有调用park()，则调用unpark方法后，再调用park方法，其会立即返回
    LockSupport.unpark(t2);
  }
}
